﻿#include "FITKTableWidget.h"

#include <QTableWidget>
#include <QMenu>
#include <QHeaderView>
#include <QKeyEvent>
#include <QLineEdit>
#include <QScrollBar>

namespace Comp
{
    FITKTableWidget::FITKTableWidget(QWidget * parent):
        QTableWidget(parent)
    {
        //TableWidget布局
        this->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
        //设置tableWidget的item点击即可编辑
        this->setEditTriggers(QAbstractItemView::AllEditTriggers);
        //TableWidget自适应大小
        //this->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

        //TableWidget鼠标右键事件信号连接
        this->setContextMenuPolicy(Qt::CustomContextMenu);

        //上下文菜单信号连接
        connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(handleContextMenu(const QPoint&)));

        ////垂直滚动条样式
        //this->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}"
        //    "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
        //    "QScrollBar::handle:hover{background:gray;}"
        //    "QScrollBar::sub-line{background:transparent;}"
        //    "QScrollBar::add-line{background:transparent;}");

        ////水平滚动条样式
        //this->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 10px;}"
        //    "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
        //    "QScrollBar::handle:hover{background:gray;}"
        //    "QScrollBar::sub-line{background:transparent;}"
        //    "QScrollBar::add-line{background:transparent;}");

        //默认添加一行数据
        insertNewRow(0);
    }

    FITKTableWidget::~FITKTableWidget()
    {

    }

    void FITKTableWidget::setAppendLineByEnterPressed(bool isAppend)
    {
        _isAddLineByEnter = isAppend;
    }

    void FITKTableWidget::setIsAloneRow(bool isAlone)
    {
        _isAloneRow = isAlone;
        if (_isAloneRow) {
            _isAddLineByEnter = false;
        }
        else {
            _isAddLineByEnter = true;
        }
    }

    void FITKTableWidget::cutCurrentData()
    {
        //剪切当前数据
        int colum = this->currentColumn();
        int row = this->currentRow();

        QTableWidgetItem* item = this->item(row, colum);
        if (item == nullptr)return;
        QString text = item->text();
        _copyValue = text;
        item->setText("");
    }

    void FITKTableWidget::copyCurrentData()
    {
        //拷贝当前数据
        int colum = this->currentColumn();
        int row = this->currentRow();

        QTableWidgetItem* item = this->item(row, colum);
        if (item == nullptr)return;
        QString text = item->text();
        _copyValue = text;
    }

    void FITKTableWidget::pasteCurrentData()
    {
        //粘贴当前数据
        int colum = this->currentColumn();
        int row = this->currentRow();

        QTableWidgetItem* item = this->item(row, colum);
        if (item == nullptr)return;
        item->setText(_copyValue);
    }

    void FITKTableWidget::insertRowBefore()
    {
        int curRow = this->currentRow();
        insertNewRow(curRow);
    }

    void FITKTableWidget::insertRowAfter()
    {
        int curRow = this->currentRow() + 1;
        insertNewRow(curRow);
    }

    void FITKTableWidget::deleteTableRows()
    {
        //删除一行
        QItemSelection selection(this->selectionModel()->selection());
        QList< int >   rows;
        foreach(const QModelIndex& index, selection.indexes())
        {
            int row = index.row();
            if (!rows.contains(row))
            {
                rows.append(row);
            }
        }
        qSort(rows);
        for (int i = rows.count() - 1; i >= 0; i--)
        {
            this->removeRow(rows[i]);
        }

        if (this->rowCount() == 0)
        {
            insertNewRow(0);
        }
    }

    void Comp::FITKTableWidget::clearContents()
    {
        //清除单元格
        QTableWidgetItem* item = this->currentItem();
        if (item != nullptr){
            item->setText("");
        }
    }

    void Comp::FITKTableWidget::clearTable()
    {
        for (int i = 0; i < this->rowCount(); i++){
            for (int j = 0; j < this->columnCount(); j++) {
                QTableWidgetItem* item = new QTableWidgetItem("");
                /*item0->setTextAlignment(Qt::AlignCenter);
                item1->setTextAlignment(Qt::AlignCenter);*/
                this->setItem(i, j, item);
            }
        }
    }

    void Comp::FITKTableWidget::keyPressEvent(QKeyEvent * event)
    {
        QTableWidget::keyPressEvent(event);

        // 获取按键值，只处理enter和return键
        int key = event->key();
        if (key != Qt::Key_Enter && key != Qt::Key_Return)
            return;
        // 获取当前选中单元格的索引
        QModelIndex index = currentIndex();
        if (!index.isValid())
            return;
        int row = index.row();
        int column = index.column();

        // 如果当前列不是最后一列，则移动到下一列
        /*if (column < columnCount() - 1)
        {
            int nextVisiablecolumn = column + 1;
            while (nextVisiablecolumn < columnCount())
            {
                if (!isColumnHidden(nextVisiablecolumn))
                {
                    setCurrentCell(row, nextVisiablecolumn);
                    edit(index.siblingAtColumn(nextVisiablecolumn));
                    break;
                }
                ++nextVisiablecolumn;
            }
        }*/
        // 如果当前行为非最后一行，则移动到下一行
        if (row < rowCount() - 1)
        {
            setCurrentCell(row + 1, column);
            edit(index.sibling(row + 1, column));
        }
        // 如果配置了按下Enter键添加新行，则添加新行
        else if (_isAddLineByEnter)
        {
            insertRow(rowCount());
            for (int i = colorCount() - 1; i >= 0; --i)
            {
                setItem(rowCount(), i, new QTableWidgetItem(""));
            }
            setCurrentCell(row + 1, column);
            edit(index.sibling(row + 1, column));
        }
    }

    void Comp::FITKTableWidget::keyReleaseEvent(QKeyEvent * event)
    {
        QTableWidget::keyReleaseEvent(event);
    }

    bool Comp::FITKTableWidget::edit(const QModelIndex & index, EditTrigger trigger, QEvent * event)
    {
        auto result = QTableWidget::edit(index, trigger, event);
        QList<QLineEdit*> lineEdits = findChildren<QLineEdit*>();
        for (int i = 0; i < lineEdits.size(); i++)
        {
            // 重写方法，屏蔽编辑框的右键菜单
            QLineEdit* target = lineEdits.at(i);
            target->setContextMenuPolicy(Qt::NoContextMenu);
        }
        return result;
    }

    void FITKTableWidget::handleContextMenu(const QPoint & pos)
    {
        Q_UNUSED(pos);
        //TableWidget上右键事件添加
        QMenu   menu(this);
        QAction* cutAction = new QAction(tr("Cut"), &menu);
        connect(cutAction, SIGNAL(triggered()), this, SLOT(cutCurrentData()));
        menu.addAction(cutAction);

        QAction* copyAction = new QAction(tr("Copy"), &menu);
        connect(copyAction, SIGNAL(triggered()), this, SLOT(copyCurrentData()));
        menu.addAction(copyAction);

        QAction* pasteAction = new QAction(tr("Paste"), &menu);
        connect(pasteAction, SIGNAL(triggered()), this, SLOT(pasteCurrentData()));
        menu.addAction(pasteAction);
        menu.addSeparator();

        if (!_isAloneRow) {
            QAction* insertBefore = new QAction(tr("Insert Row Before"), &menu);
            connect(insertBefore, SIGNAL(triggered()), this, SLOT(insertRowBefore()));
            menu.addAction(insertBefore);

            QAction* insertAfter = new QAction(tr("Insert Row After"), &menu);
            connect(insertAfter, SIGNAL(triggered()), this, SLOT(insertRowAfter()));
            menu.addAction(insertAfter);
            menu.addSeparator();

            QAction* delRows = new QAction(tr("Delete Rows"), &menu);
            connect(delRows, SIGNAL(triggered()), this, SLOT(deleteTableRows()));
            QItemSelectionModel* select = this->selectionModel();
            menu.addAction(delRows);
            if (!select->hasSelection())
            {
                insertBefore->setEnabled(false);
                insertAfter->setEnabled(false);
                delRows->setEnabled(false);
            }
        }

        QAction* clrContents = new QAction(tr("Clear Contents"), &menu);
        connect(clrContents, SIGNAL(triggered()), this, SLOT(clearContents()));
        menu.addAction(clrContents);

        QAction* clrTable = new QAction(tr("Clear Table"), &menu);
        connect(clrTable, SIGNAL(triggered()), this, SLOT(clearTable()));
        menu.addAction(clrTable);

        menu.exec(QCursor::pos());
    }

    void Comp::FITKTableWidget::insertNewRow(int row)
    {
        this->insertRow(row);

        for (int i = 0; i < this->columnCount(); i++) {
            QTableWidgetItem* item = new QTableWidgetItem("");
            this->setItem(row, i, item);
        }
    }
}
